﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ICSharpCode.WinFormsUI.Controls.Chart3D
{
    public class ViewPort
    {
        internal double baseBeta;
        internal double baseTheta;

        private Camera camera = new Camera();
        public Camera Camera
        {
            get { return camera; }
        }

        private Coordinate3D coordinate = new Coordinate3D();
        public Coordinate3D Coordinate
        {
            get { return coordinate; }
        }

        private GraphicShapes3D graphicShapes = new GraphicShapes3D();
        public GraphicShapes3D GraphicShapes
        {
            get { return graphicShapes; }
        }

        private NChart3DControl container = null;
        internal NChart3DControl Chart
        {
            get { return container; }
        }

        private void container_MouseDown(object sender, EventArgs e)
        {
            baseBeta = Camera.Beta;
            baseTheta = Camera.Theta;          
        }

        public ViewPort(System.Windows.Forms.Control container)
        {
            this.container = (NChart3DControl)container;             
            this.container.MouseDown+=container_MouseDown;
            this.container.SizeChanged += new EventHandler((sender, e) => { DefaultCameraPosition(); });
            this.container.HandleCreated += new EventHandler((sender, e) => { DefaultCameraPosition(); });
            this.coordinate = new Coordinate3D(this) { Font = this.container.Font };
            this.graphicShapes = new GraphicShapes3D(this) { Font = this.container.Font };
        }

        public void SetLookAt(int x,int y,int z)
        {
            this.camera.Location = new Vertex(x, y, z);
        }

        public void Rotate(double x, double y)
        {            
            camera.Rotate((float)(baseTheta - x * 0.01), (float)(baseBeta + y * 0.01));
            this.container.Invalidate();
        }

        public void RotateX(double x)
        {
            camera.Rotate(camera.Theta, (float)(baseBeta + x * 0.01));
            this.container.Invalidate();
        }

        public void RotateY(double y)
        {            
            camera.Rotate((float)(baseTheta - y * 0.01), camera.Beta);
            this.container.Invalidate();
        }

        public Point2D Transform2D(Vertex p)
        {
            return camera.Transform2D(p);
        }

        internal void Render(Graphics g)
        {
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            Coordinate.DrawBegin(g);  
            GraphicShapes.Draw(g);
            Coordinate.DrawEnd(g);
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
        }

        internal void DefaultCameraPosition()
        {
            if (container.IsHandleCreated)
                this.camera.Location = new Vertex((container.Width + 0) / 2, (container.Height + coordinate.Range.Height) / 2, 0);
        }

    }
}
